package busterminal.persistence.memory;

import busterminal.entity.AbstractEntity;
import busterminal.exception.BusinessException;
import busterminal.persistence.AbstractDAO;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Предок интерфейсов Data Access Object для хранения объектов в памяти
 */
public abstract class AbstractMemoryDAO<EntityType extends AbstractEntity> implements AbstractDAO<EntityType> {

    /**
     * Получить коллекцию
     * @return коллекцию
     */
    protected abstract Map<Integer, EntityType> getDataSource();

    /**
     * Получить идентификатор и увеличить его на единицу
     * @return идентификатор
     */
    protected abstract Integer getAndIncreaseCounter();

    /**
     * Добавить новую запись в коллекцию
     * @param entity запись
     */
    @Override
    public void create(EntityType entity) {
        entity.setId(getAndIncreaseCounter());
        getDataSource().put(entity.getId(), entity);
    }

    /**
     * Прочитать запись из коллекции
     * @param id идентификатор
     * @return ссылка на запись
     */
    @Override
    public EntityType read(Integer id) {
        AbstractEntity entity = getDataSource().get(id);
        if (entity == null) {
            throw new BusinessException("Entity with ID=" + id + " not found");
        }
        return getDataSource().get(id);
    }

    /**
     * Обновить запись в коллекции
     * @param entity запись
     */
    @Override
    public void update(EntityType entity) {
        getDataSource().put(entity.getId(), entity);
    }

    /**
     * Удалить запись из коллекции
     * @param entity идентификатор записи
     */
    @Override
    public void delete(EntityType entity) {
        getDataSource().remove(entity.getId());
    }

    /**
     * Удалить запись из коллекции
     * @param id идентификатор записи
     */
    @Override
    public void delete(Integer id) {
        getDataSource().remove(id);
    }

    /**
     * Получить список всех записей в коллекции
     * @return список всех записей
     */
    @Override
    public List<EntityType> findAll() {
        return new ArrayList<EntityType>(getDataSource().values());
    }
}
